#ifndef _BSP_USART_FIFO_H
#define _BSP_USART_FIFO_H

#include "stm32f4xx_hal.h"
#include <stdio.h>
#include "main.h"

/* 开关全局中断的宏 */
#define ENABLE_INT()	__set_PRIMASK(0)	/* 使能全局中断 */
#define DISABLE_INT()	__set_PRIMASK(1)	/* 禁止全局中断 */


/*
	USART1: 打印调试串口
	USART2: COM2和485接口复用的串口
	USART3: COM3和GPS扩展模块复用串口
*/
#define USART1_FIFO_EN				1
#define USART2_FIFO_EN				1
#define USART3_FIFO_EN				0 

#if USART1_FIFO_EN == 1
	#define USART1_BAUD							115200
	#define USART1_TX_BUF_SIZE			1 * 1024
	#define USART1_RX_BUF_SIZE			1 * 1024
#endif

#if USART2_FIFO_EN == 1
	#define USART2_BAUD							9600
	#define USART2_TX_BUF_SIZE			1 * 1024
	#define USART2_RX_BUF_SIZE			1 * 1024

	#define RS485_RCC_CLK_ENABLE()	__HAL_RCC_USART2_CLK_ENABLE()
	#define RS485_RCC_CLK_DISABLE()	__HAL_RCC_USART2_CLK_DISABLE()
	#define RS485_TXD_GPIO_Port			GPIOA
	#define RS485_TXD_Pin						GPIO_PIN_2
	
	#define RS485_RXD_GPIO_Port			GPIOA
	#define RS485_RXD_Pin						GPIO_PIN_3
#endif

/* 485发射、接收使能引脚 */
#define RS485_RCC_TXEN_CLK_ENABLE()				__HAL_RCC_GPIOG_CLK_ENABLE()
#define RS485_TXEN_GPIO_Port							GPIOG
#define RS485_TXEN_Pin										GPIO_PIN_8

#define RS485_TX_EN()							HAL_GPIO_WritePin(RS485_TXEN_GPIO_Port, RS485_TXEN_Pin, GPIO_PIN_SET)						
#define RS485_RX_EN()							HAL_GPIO_WritePin(RS485_TXEN_GPIO_Port, RS485_TXEN_Pin, GPIO_PIN_RESET)	

/* 定义端口号 */
typedef enum
{
	COM1 = 0,			// 用来映射到各个串口
	COM2,
	COM3,
} COM_PORT_E;

/* 串口设备结构体 */
typedef struct 
{
	UART_HandleTypeDef *uartHandle;			// HAL库串口指针
	uint8_t *pTxBuf;										// 发送缓冲区
	uint8_t *pRxBuf;										// 接收缓冲区
	uint16_t usTxBufSize;								// 发送缓冲区大小
	uint16_t usRxBufSize;								// 接收缓冲区大小
	__IO uint16_t usTxWrite;						// 发送缓冲区写指针
	__IO uint16_t usTxRead;							// 发送缓冲区读指针
	__IO uint16_t usTxCount;						// 等待发送的数据个数

	__IO uint16_t usRxWrite;						// 接收缓冲区写指针	
	__IO uint16_t usRxRead;							// 接收缓冲区读指针
	__IO uint16_t usRxCount;						// 还未读取的新数据个数

	void (*SendBefore)(void);						// 回调函数，485切换到发送模式
	void (*SendOver)(void);							// 回调函数，485切换到接收模式
	void (*ReveiveNew)(uint8_t byte);		// 串口接收的回调函数指针
} UART_T;

#if USART1_FIFO_EN == 1
	extern UART_T g_tUart1;
#endif

#if USART2_FIFO_EN == 1
	extern UART_T g_tUart2;
#endif


void bsp_InitUsart(void);

void comSendBuf(COM_PORT_E _ucPort, uint8_t *_ucBuf, uint16_t _usLen);

uint8_t comGetChar(COM_PORT_E _ucPort, uint8_t *_pByte);

void comClearTxFifo(COM_PORT_E _ucPort);

void comClearRxFifo(COM_PORT_E _ucPort);

void RS485_InitTXE(void);

void RS485_SendBefore(void);

void RS485_SendOver(void);

void RS485_SendBuf(uint8_t * _ucBuf, uint16_t _usLen);

void RS485_ReceiveNew(uint8_t _byte);

#endif

